package com.meida.module.arc.provider.iam.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.cims.sync.constant.JsonResult;
import com.cims.sync.util.SecurityUtil;
import com.meida.common.base.constants.CommonConstants;
import com.meida.module.admin.client.constants.BaseConstants;
import com.meida.module.admin.client.entity.BaseAccount;
import com.meida.module.admin.client.entity.BaseUser;
import com.meida.module.admin.provider.service.BaseAccountService;
import com.meida.module.admin.provider.service.BaseUserService;
import com.meida.module.arc.iam.utils.JsonUtil;
import com.meida.module.system.client.entity.SysConfig;
import com.meida.module.system.client.entity.SysDept;
import com.meida.module.system.provider.service.BaseConfigService;
import com.meida.module.system.provider.service.SysDeptService;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;

import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/act/common/pull")
@Log4j2
public class PullController {
    private static RestTemplate restTemplate = new RestTemplate();
    @Value("${cims.appSecret}")
    private String appSecret;
    @Value("${cims.appId}")
    private String appId;
    @Value("${cims.authUrl}")
    private String authUrl;

    @Autowired
    SysDeptService deptService;

    @Autowired
    BaseUserService baseUserService;
    @Autowired
    PasswordEncoder passwordEncoder;
    @Autowired
    BaseAccountService baseAccountService;

    @Autowired
    BaseConfigService configService;

    /**
     * PULL_ORG
     * description: 更新组织机构
     * date: 2024年-02月-18日 15:36
     * author: ldd
     *
     * @param syncTime 同步时间戳
     * @param page     分页
     * @return java.lang.Object
     */
    @GetMapping("/org")
    @ResponseBody
    public Object pullOrg(@RequestParam(required = false) String syncTime,
                          @RequestParam(required = false) Integer page) {

        SysConfig config = configService.getByProperty("configKey", "PULL_ORG");

        Map<String, Object> params = new HashMap<>();
        params.put("appId", appId);
        if (!StringUtils.isEmpty(syncTime)) {
            params.put("syncTime", syncTime);
        }
        if (page != null) {
            params.put("page", page);
        }
        if (null != config && !"0".equals(config.getConfigVal())) {
            params.put("syncTime", config.getConfigVal());
        }
        HttpHeaders headers = new HttpHeaders();
        headers.add("Authorization", "Bearer " + getToken());
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<String> mapHttpEntity = new HttpEntity<>(JsonUtil.obj2json(params), headers);
        log.info("拉取组织信息请求参数:" + JsonUtil.obj2json(params));
        log.info("拉取组织信息请rul:" + authUrl + "/rest/v1/issue/pull/org");
        ResponseEntity<JsonResult> response = restTemplate.postForEntity(authUrl + "/rest/v1/issue/pull/org", mapHttpEntity, JsonResult.class);
        JsonResult body = response.getBody();
        log.info("拉取组织信息结果:" + JsonUtil.obj2json(body));

        JSONObject obj = JSONUtil.parseObj(body.getData());
        //String body = "{\"code\":1000,\"msg\":\"成功\",\"data\":{\"taskId\":\"41b5bb683d594080a528d01a74741aea\",\"hasPaged\":false,\"currentPage\":1,\"totalPage\":1,\"total\":3,\"hasNext\":false,\"timestamp\":null,\"data\":[{\"syncType\":0,\"eventTimestamp\":1640155309828,\"createTime\":\"2021-12-22T06:41:50.018+0000\",\"taskId\":\"41b5bb683d594080a528d01a74741aea\",\"appId\":\"659240c7ae18415e945cdab21e822cd3\",\"name\":\"测试部门 2\",\"status\":\"0\",\"depNum\":\"csbm2\",\"parentNum\":null,\"parentNums\":\"csbm2\",\"sort\":0,\"attrs\":{\"depType\":\"一级部门\",\"name\":\"测试部门 2\",\"parentNum\":null,\"depNum\":\"csbm2\",\"depStatus\":\"有效\"}}]}}";
        //JSONObject obj1 = JSONUtil.parseObj(body);
        //JSONObject obj = JSONUtil.parseObj(obj1.getStr("data"));
        JSONArray data = JSONUtil.parseArray(obj.getStr("data"));
        List<SysDept> deptList = new ArrayList<>();
        for (int i = 0; i < data.size(); i++) {
            JSONObject o = (JSONObject) data.get(i);
            SysDept dept = new SysDept();
            dept.setCompanyId(1517049905770037000L);
            dept.setDeptNo(o.getStr("depNum"));
            dept.setDeptCode(o.getStr("depNum"));
            dept.setDeptName(o.getStr("name"));
            dept.setDeptState(o.getInt("status"));
            dept.setSortOrder(o.getInt("sort"));
            dept.setParentId(0L);

            SysDept deptCode = deptService.getOne(new QueryWrapper<SysDept>().eq("deptCode", dept.getDeptCode()));
            if(ObjUtil.isNotNull(deptCode)){
                dept.setDeptId(deptCode.getDeptId());
            }
            if (StrUtil.isNotEmpty(o.getStr("parentNum"))) {
                //    查找上级ID
                SysDept parent = deptService.getOne(new QueryWrapper<SysDept>().lambda().eq(SysDept::getDeptCode, o.getStr("parentNum")));
                if (parent != null) {

                    dept.setParentId(parent.getDeptId());
                }
            }
            deptList.add(dept);
        }

        if (CollUtil.isNotEmpty(deptList)) {
            deptService.saveOrUpdateBatch(deptList);

            config.setConfigVal(System.currentTimeMillis() + "");
            config.updateById();
        }

        return body;
    }

    /**
     * description: 更新人员
     * date: 2024年-02月-18日 15:36
     * author: ldd
     *
     * @param syncTime 同步时间戳
     * @param page     分页
     * @return java.lang.Object
     */
    @GetMapping("/account")
    @ResponseBody
    public Object pullAccount(@RequestParam(required = false) String syncTime,
                              @RequestParam(required = false) Integer page) {

        SysConfig config = configService.getByProperty("configKey", "PULL_USER");

        Map<String, Object> params = new HashMap<>();
        params.put("appId", appId);
        if (!StringUtils.isEmpty(syncTime)) {
            params.put("syncTime", syncTime);
        }
        if (page != null) {
            params.put("page", page);
        }
        if (null != config && !"0".equals(config.getConfigVal())) {
            params.put("syncTime", config.getConfigVal());
        }

        HttpHeaders headers = new HttpHeaders();
        headers.add("Authorization", "Bearer " + getToken());
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<String> mapHttpEntity = new HttpEntity<>(JsonUtil.obj2json(params), headers);
        log.info("拉取账号信息请求:" + JsonUtil.obj2json(params));
        ResponseEntity<JsonResult> response = restTemplate.postForEntity(authUrl + "/rest/v1/issue/pull/user", mapHttpEntity, JsonResult.class);
        JsonResult body = response.getBody();
        log.info("拉取账号信息结果:" + JsonUtil.obj2json(body));

        try {
            List<BaseUser> userList = new ArrayList<>();
            List<BaseAccount> accountList = new ArrayList<>();
            JSONObject obj = JSONUtil.parseObj(body.getData());
            //String body = "{\"code\":1000,\"msg\":\"成功\",\"data\":{\"taskId\":\"41b5bb683d594080a528d01a74741aea\",\"hasPaged\":false,\"currentPage\":1,\"totalPage\":1,\"total\":3,\"hasNext\":false,\"timestamp\":null,\"data\":[{\"syncType\":0,\"eventTimestamp\":1640157837722,\"createTime\":\"2021-12-22T07:23:57.729+0000\",\"taskId\":\"b320ae9c45674429b7078be2fa28626f\",\"appId\":\"659240c7ae18415e945cdab21e822cd3\",\"principalId\":\"cszh2\",\"password\":null,\"status\":\"0\",\"sort\":null,\"attributes\":{\"deptNums\":\",csbm2,\",\"address\":\"北京市海淀区\",\"gender\":\"男\",\"userName\":\"cszh1\"},\"deptNums\":[\"csbm2\"],\"appRoles\":[]}]}}";
            //JSONObject obj1 = JSONUtil.parseObj(body);
            //JSONObject obj = JSONUtil.parseObj(obj1.getStr("data"));
            JSONArray data = JSONUtil.parseArray(obj.getStr("data"));
            for (int i = 0; i < data.size(); i++) {
                JSONObject o = (JSONObject) data.get(i);
                BaseUser user = new BaseUser();
                user.setCompanyId(1517049905770037000L);

                user.setNickName(o.getStr("principalId"));
                user.setUserName(o.getStr("principalId"));
                user.setAccount(o.getStr("principalId"));
                user.setPassword(o.getStr("password"));
                user.setStatus(o.getInt("status"));
                BaseUser userByUsername = baseUserService.getUserByUsername(user.getAccount());
                if (ObjUtil.isNull(userByUsername)) {
                    user.setUserId(IdWorker.getId());
                } else {
                    user.setUserId(userByUsername.getUserId());
                }
                user.setStatus(CommonConstants.ENABLED);
                user.setUserType(CommonConstants.ENABLED_STR);
                String pwd = StrUtil.isEmpty(o.getStr("password")) ? "zbao@6888" : o.getStr("password");
                String encodePassword = passwordEncoder.encode(pwd);
                user.setPassword(encodePassword);
                JSONArray deptNums = o.getJSONArray("deptNums");
                SysDept one = deptService.getOne(new QueryWrapper<SysDept>().lambda().eq(SysDept::getDeptCode, deptNums.get(0)));
                user.setDeptId(one.getDeptId());
                userList.add(user);
                BaseAccount baseAccount = new BaseAccount(user.getUserId(), user.getUserName(), user.getPassword(), BaseConstants.USER_ACCOUNT_TYPE_USERNAME, BaseConstants.ACCOUNT_DOMAIN_ADMIN, null);
                baseAccount.setStatus(CommonConstants.ENABLED);
                accountList.add(baseAccount);

            }
            if (CollUtil.isNotEmpty(userList)) {
                baseUserService.saveOrUpdateBatch(userList);
                baseAccountService.saveOrUpdateBatch(accountList);
           /* for (BaseUser user : userList) {

                baseUserService.saveDept(user.getUserId(), );
            }*/

                config.setConfigVal(System.currentTimeMillis() + "");
                config.updateById();
            }
        } catch (Exception e) {
            log.error("拉取用户异常", e.getMessage());
        }


        return body;
    }

    public String getToken() {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        LinkedMultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
//        params.add("grant_type", "client_credentials");
        params.add("client_id", appId);
        params.add("client_secret", appSecret);
        String token = "";

        try {
            String str = "{\"grantType\":\"client_credentials\"}";

            String url = authUrl + "/oauth/token?clientId=" + appId + "&clientSecret=" + appSecret;

            log.info("token:" + url);
            url = authUrl + "/oauth/token?clientId=" + URLEncoder.encode(appId, "UTF-8") + "&clientSecret=" + URLEncoder.encode(appSecret, "UTF-8");
            log.info("token encode:" + url);

            HttpRequest post = HttpUtil.createPost(url);
            post.form("clientId", appId);
            post.form("clientSecret", appSecret);
            post.body(str);
            String body = post.execute().body();
            com.alibaba.fastjson.JSONObject jsonObject = JSON.parseObject(body);
            if (jsonObject.getIntValue("code") == 1000) {
                token = jsonObject.getJSONObject("data").getString("token");
            }
            System.out.println(body);
//        HttpEntity<LinkedMultiValueMap<String, Object>> mapHttpEntity = new HttpEntity<>(params, httpHeaders);
            /*HttpEntity<String  > mapHttpEntity = new HttpEntity<String>(str, httpHeaders);
        ResponseEntity<JsonResult> rResponseEntity = restTemplate.postForEntity(authUrl + "/oauth/token", mapHttpEntity,  JsonResult.class);
        JsonResult rt = rResponseEntity.getBody();
        if (rt.getCode() == 1000) {
            token = JsonUtil.pojo2map(rt.getData()).get("token").toString();
        }
        log.info("获取token：" + token);
*/


           /* HttpHeaders headers=new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            Map map=new HashMap();
            map.put("clientId", appId);
            map.put("clientSecret", appSecret);
            HttpEntity<String> entity=new HttpEntity<String>(str,headers);
            ResponseEntity exchange = restTemplate.exchange(authUrl + "/oauth/token?clientId="+appId+"&clientSecret="+appSecret, HttpMethod.POST, entity, String.class, map);
            Object body1 = exchange.getBody();
            System.out.println(body1);*/

        } catch (Exception x) {
            x.printStackTrace();
        }
        return token;
    }


    public static void main(String[] args) {

        try {
//            AesUtils util=new AesUtils("1122334yq5667788");
//            System.out.println( util.decryptData("KuIg3hE2w/ClI+KPpkzyuQ=="));

            SecurityUtil.decryptAES("KuIg3hE2w/ClI+KPpkzyuQ==", "1122334yq5667788");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }
}
